# !/usr/bin/evn python3
# -*- coding: utf-8 -*-
# File Name: user.py
# Created Date: 2017-11-24 10:41:21
from app.extra import *
import hashlib
from werkzeug.security import generate_password_hash, check_password_hash
from .account import Account
from .user_account import user_accounts

class User(db.Model, Modelable, Serialize):
    __tablename__ = 'users'
    __searchable__ = ["name", "phone"]
    __analyzer__ = ChineseAnalyzer()
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128), index=True)
    phone = db.Column(db.String(128), nullable=False, index=True, unique=True)
    password_hash = db.Column(db.String(128))
    image = db.Column(db.String)
    token = db.Column(db.String(128), index=True)
    amount = db.Column(db.Integer, default=0)
    score = db.Column(db.Integer, default=0)
    lock = db.Column(db.Boolean, default=False)
    geohash = db.Column(db.String, index=True)
    updated_at = db.Column(db.Integer, default=time.mktime(datetime.utcnow().timetuple()), onupdate=time.mktime(datetime.utcnow().timetuple()))
    created_at = db.Column(db.Integer, default=time.mktime(datetime.utcnow().timetuple()))
    orders = db.relationship("Order", foreign_keys="Order.user_id", lazy="dynamic")
    server_orders = db.relationship("Order", foreign_keys="Order.server_id", lazy="dynamic")
    driver_orders = db.relationship("Order", foreign_keys="Order.driver_id", lazy="dynamic")
    accounts = db.relationship("Account", secondary=user_accounts, lazy="subquery", backref=db.backref("users", lazy=True))
    
    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)
        self.token = hashlib.sha1(app.config['SECRET_KEY'].encode('utf-8')).hexdigest()

    def __repr__(self):
        return "<User: {}, {}, {}>".format(self.id, self.name, self.phone)

    def __str__(self):
        return "user"

    @property
    def password(self):
        raise AttributeError('密码解析失败')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)
    
    @property
    def generate_token(self):
        pay = Serializer(current_app.config['SECRET_KEY'], expires_in=3600*24*365*20)
        token = pay.dumps({'user_id': self.id, 'token': self.token})
        return token

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def conver_token(token):
        pay = Serializer(current_app.config['SECRET_KEY'])
        try:
            arg = pay.loads(token)
            user = User.query.filter_by(id=arg["user_id"], token=arg["token"]).first()
        except:
            return False
        return user

    @classmethod
    def signup(cls, **kwargs):
        user = User.query.filter_by(phone=kwargs["phone"]).first()
        if user:
            return False, "手机号被注册"
        else:
            user = cls(**kwargs)
            db.session.add(user)
            db.session.commit()
            return True, user


        
    #生成测试数据
    @staticmethod
    def generate_fake_user(count=100):
        from random import seed, randint
        import forgery_py
        
        for i in range(10):
            a = Account(name=forgery_py.name.full_name(), nickname=forgery_py.address.state_abbrev())
            db.session.add(a)
            try:
                db.session.commit()
            except Exception as e:
                print("错误>>{}".format(e))
                db.session.rollback()
        
        seed()        
        a_c = Account.query.count()
        temps = [
                (31.222, 121.345), 
                (30.111, 121.645), 
                (31.567, 120.345),
                (31.234, 121.845),
                (31.734, 121.111)
                ]

        for i in range(count):
            a = Account.query.offset(randint(0, a_c-1)).first()
            g = geohash.encode(*temps[randint(0, len(temps) -1)])
            u = User(name=forgery_py.name.full_name(), phone=forgery_py.address.phone(), password=forgery_py.address.phone(), geohash=g)
            u.accounts.append(a)
            db.session.add(u)
            try:
                db.session.commit()
            except Exception as e:
                print("##错误{}".format(e))
                db.session.rollback()

whooshalchemy.whoosh_index(app, User)
